﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using Pavilion.GameTools;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Pavilion.DesignerTool.ViewTools.ConnectableListBox;
using GalaSoft.MvvmLight.Command;
using Pavilion.DesignerTool.NodeDesignerTool.Scripting;
using System.Xml.Linq;
using System.IO;
using Pavilion.DesignerTool.ViewTools;

namespace Pavilion.DesignerTool
{
    public class NodeDesignerToolViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public event Action<object> SelectedItemChanged;

        public ObservableCollection<NodeScriptViewModel> NodeScriptViewModelCollection { get; private set; }
        public NodeScriptViewModel CurrentNodeScriptViewModel { get { return currentNodeScriptViewModel; } set { SetCurrentNodeScriptViewModel(value); } }

        private NodeScriptViewModel currentNodeScriptViewModel;

        public NodeDesignerToolViewModel()
        {
            NodeScriptViewModelCollection = new ObservableCollection<NodeScriptViewModel>();
        }

        public void LoadNodeScript(NodeScriptWrapper nodeScriptWrapper)
        {
            NodeScriptViewModel nodeScriptViewModel = new NodeScriptViewModel();
            nodeScriptViewModel.NodeScriptWrapper = nodeScriptWrapper;

            nodeScriptWrapper.Disposed += RemoveViewModels;

            NodeScriptViewModelCollection.Add(nodeScriptViewModel);
            CurrentNodeScriptViewModel = nodeScriptViewModel;
            OnPropertyChanged("CurrentNodeScriptViewModel");
        }

        private void RemoveViewModels(NodeScriptWrapper nodeScriptWrapper)
        {
            bool resetCurrent = false;
            IEnumerable<NodeScriptViewModel> viewModels = NodeScriptViewModelCollection.Where((x) => x.NodeScriptWrapper == nodeScriptWrapper).ToArray();

            foreach (NodeScriptViewModel viewModel in viewModels)
            {
                NodeScriptViewModelCollection.Remove(viewModel);

                if (viewModel == CurrentNodeScriptViewModel)
                    resetCurrent = true;
            }

            if (resetCurrent)
                CurrentNodeScriptViewModel = viewModels.FirstOrDefault();
        }

        private void SetCurrentNodeScriptViewModel(NodeScriptViewModel value)
        {
            if (currentNodeScriptViewModel == value)
                return;

            if (currentNodeScriptViewModel != null)
                currentNodeScriptViewModel.SelectedItemChanged -= OnSelectedItemChanged;

            currentNodeScriptViewModel = value;

            if (currentNodeScriptViewModel != null)
            {
                currentNodeScriptViewModel.SelectedItemChanged += OnSelectedItemChanged;
                OnSelectedItemChanged(currentNodeScriptViewModel.SelectedItem);
            }
        }

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private void OnSelectedItemChanged(object selectedItem)
        {
            if (SelectedItemChanged != null)
                SelectedItemChanged(selectedItem);
        }

        private class NodeScriptViewModelComparer : IEqualityComparer<NodeScriptViewModel>
        {
            public bool Equals(NodeScriptViewModel x, NodeScriptViewModel y) { return x.NodeScriptWrapper == y.NodeScriptWrapper; }
            public int GetHashCode(NodeScriptViewModel obj) { return obj.NodeScriptWrapper.GetHashCode(); }
        }
    }
}
